// **************************************************************
// Com ++ Framework by the C++ World
// Please report defects: mailto:compp@cplusplusworld.com
// Please visit: http://www.cplusplusworld.com/socketlibrary.html
// **************************************************************

#include "ComPlusPlus/Directory.h"
//#include "config.h"

#include <regex.h>


compp::Directory::Directory() {

  SortModesAsc = true;

}

void compp::Directory::setPath( const std::string & Path, const std::string & Filter  ) {

  SortModesAsc = true;

  CreateListing ( Path, Filter );
  DirPath = Path;

}


compp::Directory::Directory( const std::string & Path, const std::string & Filter ) {

  setPath(Path, Filter);

}

compp::Directory::~Directory() {


}

std::list<compp::DirEntry>::iterator  compp::Directory::getFirst() {

  return DirectoryList.begin();
  

}

std::list<compp::DirEntry>::iterator  compp::Directory::end() {

  return DirectoryList.end();
  
}


void compp::Directory::Refresh() {

  CreateListing ( DirPath );

}

void compp::Directory::SortName(){
  
  if ( SortModesAsc ) 
    DirectoryList.sort ( compp::DirEntry::lessName );
  else
    DirectoryList.sort ( compp::DirEntry::greaterName );

}

void compp::Directory::setSortAsc() {

  SortModesAsc = true;

}

void compp::Directory::setSortDesc() {

  SortModesAsc = false;

}

void compp::Directory::CreateListing( const std::string & s, const std::string & Filter ) {

  regex_t reg;
  if ( Filter != "" ) {
    if ( 0 !=  regcomp( & reg, Filter.c_str(), REG_EXTENDED ) ) {
      std::string errstr = "Regex " ;
      errstr += Filter ;
      errstr += " is invalid." ;
      throw syspp::ComException ( errstr.c_str() );
    }
  }

  if ( ! DirectoryList.empty () ) {
    DirectoryList.clear();
  }

  DIR *de;
  struct dirent *di;

  de = opendir( s.c_str() );
  
  if ( de == NULL ) {
    std::string errstr = "Directory " ;
    errstr += s ;
    errstr += " does not exist" ;
    throw syspp::ComException ( errstr.c_str() );
  }

  while ( NULL != ( di = readdir(de) ) ) {
    std::string full = s;
    full += "/";
    full += di->d_name;

    compp::DirEntry e;
    e.setPath (full);

    if ( Filter != "" ) {
      regmatch_t pmatch[256];
      if ( 0 ==  regexec( &reg, full.c_str(), 1 ,  pmatch, 0) )
	DirectoryList.push_back ( e );
    } else 
      DirectoryList.push_back ( e );
  }
  closedir ( de );
}

